package cn.darkhorse.ticket.production.service.impl;

import cn.darkhorse.ticket.basis.pojo.TicketProduct;
import cn.darkhorse.ticket.basis.service.TicketProductService;
import cn.darkhorse.ticket.code.RepeatCheck;
import cn.darkhorse.ticket.constants.TicketConstants;
import cn.darkhorse.ticket.production.dto.TicketInfoDTO;
import cn.darkhorse.ticket.production.pojo.TicketInfo;
import cn.darkhorse.ticket.production.mapper.TicketInfoMapper;
import cn.darkhorse.ticket.production.pojo.TicketProductionPlanInfo;
import cn.darkhorse.ticket.production.pojo.TicketProductionPlanProductInfo;
import cn.darkhorse.ticket.production.pojo.TicketTask;
import cn.darkhorse.ticket.production.service.TicketInfoService;
import cn.darkhorse.ticket.production.service.TicketProductionPlanInfoService;
import cn.darkhorse.ticket.production.service.TicketProductionPlanProductInfoService;
import cn.darkhorse.ticket.production.service.TicketTaskService;
import cn.darkhorse.ticket.production.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.security.krb5.internal.Ticket;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 工单管理 服务实现类
 * </p>
 *
 * @author maoguanjun
 * @since 2024-01-30
 */
@Service
public class TicketInfoServiceImpl extends ServiceImpl<TicketInfoMapper, TicketInfo> implements TicketInfoService {
    @Resource
    private TicketInfoMapper ticketInfoMapper;
    @Resource
    private RepeatCheck<TicketInfo> repeatCheck;
    @Resource
    private TicketTaskService ticketTaskService;
    @Resource
    private TicketProductionPlanInfoService ticketProductionPlanInfoService;
    @Resource
    private TicketProductionPlanProductInfoService ticketProductionPlanProductInfoService;
    @Resource
    private TicketProductService ticketProductService;
    @Resource
    private ISysDictTypeService iSysDictTypeService;
    /**
     * 列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<TicketInfoVO> listAll(TicketInfoDTO dto) {
        List<TicketInfoVO> voList=ticketInfoMapper.listAll(dto);
        if(null!=voList&&voList.size()>0){
            List<String> collect = voList.stream().map(TicketInfo::getCode).collect(Collectors.toList());
            Map<String, List<TicketTaskScheduleVO>> stringListMap = ticketTaskService.viewOfTaskSchedule(collect);
            // 生产计划状态
            List<SysDictData> planSection = iSysDictTypeService.selectDictDataByType("ticket_status");
            Map<String, String> ticketData = planSection.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

            voList.forEach(item->{
                if(stringListMap.containsKey(item.getCode())){
                    item.setTicketTaskScheduleVOS(stringListMap.get(item.getCode()));
                }
                if(ticketData.containsKey(item.getStatus().toString())){
                    item.setStatusName(ticketData.get(item.getStatus().toString()));
                }
            });
        }
        return voList;
    }

    /**
     * 保存
     *
     * @param info
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTicket(TicketInfoVO info) {
        boolean save = save(info);
        if(info.getPlanedStartTime().compareTo(info.getPlanedEndTime())>0){
            throw new ServiceException("计划开始时间不能晚于计划结束时间!");
        }
        if(null==info.getTicketTask()){
            throw new ServiceException("生产任务不能为空!");
        }
        info.getTicketTask().forEach(item->{
            if(item.getPlanedEndTime().compareTo(info.getPlanedEndTime().toLocalDate())>0){
                throw new ServiceException("工序任务的计划结束时间不能迟于整体工单的结束时间!");
            }
            item.setTicketInfoCode(info.getCode());
        });
        //保存工序任务
        ticketTaskService.add(info.getTicketTask());
        return save;
    }

    /**
     * 查看
     *
     * @param dataId
     * @return
     */
    @Override
    public TicketInfoViewVO view(Long dataId) {
        TicketInfoViewVO vo=new TicketInfoViewVO();
        TicketInfo byId = getById(dataId);
        if(null!=byId){
            TicketProductionPlanInfoViewVO plan = ticketProductionPlanInfoService.view(byId.getPlanId());
            TicketProduct product = ticketProductService.getById(byId.getProductId());
            if(null!=plan){
                vo.setPlanSource(plan.getSource());
                vo.setRelatedNum(plan.getRelatedNum());
                vo.setPlanSourceName(plan.getSourceName());
                vo.setCreatorName(plan.getCreatorName());
                if(null!=plan.getProductionPlanProductInfoList()){
                    Map<Long, TicketProductionPlanProductInfoVO> collect = plan.getProductionPlanProductInfoList().stream().collect(Collectors.toMap(TicketProductionPlanProductInfo::getProductId, Function.identity()));
                    if(collect.containsKey(byId.getProductId())){
                        vo.setProductTypeName(collect.get(byId.getProductId()).getProductTypeName());
                    }
                }
            }
            if(null!=product){
                vo.setModel(product.getModel());
                vo.setQuality(product.getQuality());
                vo.setWeight(product.getWeight());
                vo.setProductTypeId(product.getProductTypeId());
            }
            BeanUtils.copyProperties(byId,vo);
            List<TicketTaskListVO> ticketTaskListVOS = ticketTaskService.viewOfTicketInfo(vo.getCode());
            vo.setTicketTask(ticketTaskListVOS);
        }
        return vo;
    }

    /**
     * 开始
     *
     * @param dataId
     * @return
     */
    @Override
    public boolean start(Long dataId) {
        TicketInfo info = getById(dataId);
        if(null==info){
            throw new ServiceException("无效工单！");
        }
        if(info.getStatus()!=TicketConstants.TICKET_STATUS_NOT_START){
            throw new ServiceException("只有未开始的工单可以开始!");
        }
        info.setStatus(TicketConstants.TICKET_STATUS_ONGOING);
        info.setRealStartTime(LocalDateTime.now());
        boolean resutlt = updateById(info);
        ticketTaskService.modifyProcedureStates(info.getCode(),TicketConstants.TICKET_STATUS_ONGOING);
        return resutlt;
    }

    /**
     * 结束
     *
     * @param dataId
     * @return
     */
    @Override
    public boolean end(Long dataId) {
        TicketInfo info = getById(dataId);
        if(info.getStatus()!=TicketConstants.TICKET_STATUS_ONGOING){
            throw new ServiceException("只有进行中的工单可以结束!");
        }
        info.setStatus(TicketConstants.TICKET_STATUS_END);
        info.setRealEndTime(LocalDateTime.now());
        boolean result = updateById(info);
        ticketTaskService.modifyProcedureStates(info.getCode(),TicketConstants.TICKET_STATUS_END);

        return result;
    }

    /**
     * 开始校验
     *
     * @param dataId
     * @return
     */
    @Override
    public boolean startCheck(Long dataId) {
        TicketInfo info = getById(dataId);
        if(null==info){
            throw new ServiceException("无效工单！");
        }
        if(info.getStatus()!=TicketConstants.TICKET_STATUS_NOT_START){
            throw new ServiceException("只有未开始的工单可以开始!");
        }
        boolean canStartOfTicket = ticketTaskService.isCanStartOfTicket(info.getCode());
        return canStartOfTicket;
    }

    /**
     * 结束校验
     *
     *
     * @param dataId
     * @return
     */
    @Override
    public boolean endCheck(Long dataId) {
        TicketInfo info = getById(dataId);
        if(null==info){
            throw new ServiceException("无效工单！");
        }
        if(info.getStatus()!=TicketConstants.TICKET_STATUS_ONGOING){
            throw new ServiceException("只有进行中的工单可以结束!");
        }
        LambdaQueryWrapper<TicketTask> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(TicketTask::getTicketInfoCode,info.getCode());
        wrapper.ne(TicketTask::getProcedureStates,TicketConstants.TICKET_STATUS_END);
        wrapper.ne(TicketTask::getProcedureStates,TicketConstants.TICKET_STATUS_CANCEL);
        long count = ticketTaskService.count(wrapper);
        if (count > 0) {
            return true;
        }
        return false;
    }

    /**
     * 取消
     *
     * @param dataId
     * @return
     */
    @Override
    public boolean cancel(Long dataId) {
        TicketInfo info = getById(dataId);
        if(null==info){
            throw new ServiceException("无效工单！");
        }
        //TODO产品放开限制，随意取消
        /*
        if(info.getStatus()!=TicketConstants.TICKET_STATUS_NOT_START){
            throw new ServiceException("只有未开始的工单可以取消!");
        }*/
        info.setStatus(TicketConstants.TICKET_STATUS_CANCEL);
        boolean resutlt = updateById(info);
        ticketTaskService.modifyProcedureStates(info.getCode(),TicketConstants.TICKET_STATUS_CANCEL);
        return resutlt;
    }
}
